
package com.jgp.workflow.controller;

import com.jgp.common.annotation.UIParam;
import com.jgp.common.pojo.TreeBean;
import com.jgp.security.config.SecUserAdapter;
import com.jgp.security.pojo.UserInfo;
import com.jgp.sys.controller.JGPBackController;
import com.jgp.sys.ui.GridResult;
import com.jgp.sys.ui.Pager;
import com.jgp.sys.ui.Result;
import com.jgp.workflow.exception.WorkflowException;
import com.jgp.workflow.pojo.*;
import com.jgp.workflow.service.ProcessService;
import com.jgp.workflow.utils.ProcessUtil;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;

/**
 * 项目   jgp-cloud-parent
 * 作者   loufei
 * 时间   2018/11/26
 */
@CrossOrigin
@RestController
@RequestMapping({"/workflow/processApiController","/mobile/workflow/process-api-ctl"})
public class ProcessApiController extends JGPBackController {
    
    @Autowired
    private ProcessService processService;
    @Autowired
    private SecUserAdapter userAdapter;
    
    @RequestMapping("publish")
    public Result publish(String modelId) throws IOException {
        return ajaxRe(processService.publishProcess(modelId));
    }
    
    @RequestMapping("queryPicBeforeStart")
    public void queryPicBeforeStart(String defKey, HttpServletResponse response) throws IOException {
        InputStream in = processService.queryProcessPic(defKey);
        copyPic(in, response.getOutputStream());
    }
    
    @RequestMapping("queryProcessPic")
    public void queryProcessPic(String processInsId, HttpServletResponse response) throws Exception {
        InputStream in = processService.queryProcessStatePic(processInsId);
        copyPic(in, response.getOutputStream());
    }
    
    @RequestMapping("/queryProcessDef")
    public Result queryProcessDef(@UIParam("pager") Pager pager) {
        List<ViewProcessDef> processDefs = processService.queryAllProcessDef(pager);
        
        List<GridResult.Category> categories = new ArrayList<>();
        categories.add(new GridResult.Category("流程名", "defName"));
        categories.add(new GridResult.Category("版本", "version"));
        //categories.add(new GridResult.Category("key", "key"));
        categories.add(new GridResult.Category("类别", "category"));
        categories.add(new GridResult.Category("KEY", "defKey"));
        return ajaxReGrid("gdata", categories, processDefs, pager);
    }
    /**
     * 查询指定人待审批的任务
     *
     * @param userId
     * @return
     */
    @RequestMapping("queryNotHandledTask/{userId}")
    public Result queryNotHandledTask(@PathVariable("userId") String userId,String sn,String procName,String taskName, String specialInstitutionKey,@UIParam("pager") Pager pager) {
        if(StringUtils.isBlank(specialInstitutionKey)){
            specialInstitutionKey = "GLDW";
        }
        Result result = queryNotHandledTask2( sn, procName,taskName,specialInstitutionKey,userId, pager.getCurrent(), pager.getPageSize());
        Object list = result.getData("tasks");
        if(Objects.nonNull(list)){
            return ajaxReGrid("gdata", categories(), (List<ViewProcessTask>)list, (Pager)result.getData("pager"));
        }else{
            List<ViewProcessTask> empty = new ArrayList<>();
            return ajaxReGrid("gdata", categories(), empty, pager);
        }
    }
    
    /**
     *
     * @param sn
     * @param taskName
     * @param specialInstitutionKey
     * @param userId
     * @param current
     * @param pageSize
     * @return
     */
    @RequestMapping(value = "query-not-handled-task/{userId}/{current}/{pageSize}",method = RequestMethod.POST)
    public Result queryNotHandledTask2(String sn,String procName,String taskName,
                                       String specialInstitutionKey,
                                       @PathVariable("userId") String userId,
                                       @PathVariable("current") Integer current,
                                       @PathVariable("pageSize") Integer pageSize) {
        Pager pager = new Pager(current,pageSize);
        UserInfo userInfo = userAdapter.currentUser();
        List<String> groupIds = ProcessUtil.transformGroups(userInfo);
        if(StringUtils.isBlank(specialInstitutionKey)){
            specialInstitutionKey = "GLDW";
        }
        List<String> ins = ProcessUtil.specialInstitutions(userInfo,specialInstitutionKey);
        List<ViewProcessTask> list = processService.queryNotHandledTask(userId,sn,procName,taskName, groupIds,ins, pager);
        return ajaxReData("tasks", list).addData("pager",pager);
    }
    
    /**
     * 发起并未传递
     * @param userId
     * @param pager
     * @return
     */
    @RequestMapping("queryApplyButNotPass/{userId}")
    public Result queryApplyButNotPass(@PathVariable("userId") String userId, @UIParam("pager") Pager pager) {
        List<ViewProcessTask> list = processService.queryApplyButNotPass(userId, pager);
        return ajaxReGrid("gdata", notPassCategories(), list, pager);
    }
    
    /**
     * 发起并未传递
     * @param userId
     * @param pager
     * @return
     */
    @RequestMapping("query-apply-but-not-pass/{userId}")
    public Result queryApplyButNotPass2(@PathVariable("userId") String userId, @UIParam("pager") Pager pager) {
        List<ViewProcessTask> list = processService.queryApplyButNotPass(userId, pager);
        return ajaxReData("tasks", list).addData("pager",pager);
    }
    
    /**
     * 查询指定用已办任务
     *
     * @return
     */
    @RequestMapping("queryCompletedTask")
    public Result queryCompletedTask(String userId, @UIParam("pager") Pager pager) {
        List<ViewProcessTask> list = processService.queryCompletedTask(userId, pager);
        return ajaxReGrid("gdata", completeCategories(), list, pager);
    }
    
    /**
     * 查询指定用已办任务
     * 移动端
     * @return
     */
    @RequestMapping(value = "query-completed-task/{userId}/{current}/{pageSize}",method = RequestMethod.POST)
    public Result queryCompletedTask2(@PathVariable("userId") String userId,
                                      @PathVariable("current") Integer current,
                                      @PathVariable("pageSize") Integer pageSize) {
        Pager pager = new Pager(current,pageSize);
        List<ViewProcessTask> list = processService.queryCompletedTask(userId, pager);
        return ajaxReData("tasks", list).addData("pager",pager);
    }
    
    
    /**
     * 查询指定用户发起的流程
     *
     * @param query
     * @return
     */
    @RequestMapping("queryProcess")
    public Result queryInitiatedProcess(QueryWorkOrderForm query, @UIParam("pager") Pager pager) {
        List<ViewProcessIns> list = processService.queryWorkOrder(query, pager);
        List<GridResult.Category> categories = new ArrayList<>();
        categories.add(new GridResult.Category("工单号", "sn"));
        categories.add(new GridResult.Category("工单类型", "name"));
        categories.add(new GridResult.Category("工单内容", "orderContent"));
//        categories.add(new GridResult.Category("传递状态", "applyNode"));
        categories.add(new GridResult.Category("发起时间", "createTime"));
        categories.add(new GridResult.Category("完成时间", "completeTime"));
        return ajaxReGrid("gdata", categories, list, pager);
    }
    
    
    /**
     * 查询指定用户发起的流程
     * 移动端
     * @param query
     * @return
     */
    @RequestMapping(value = "query-process",method = RequestMethod.POST)
    public Result queryInitiatedProcess2(@RequestBody QueryWorkOrderForm query) {
        List<ViewProcessIns> list = processService.queryWorkOrder(query, query.getPager());
        return ajaxReData("processes",list).addData("pager",query.getPager());
    }
    
    /**
     * 查询流程实例任务执行列表
     *
     * @param procId
     * @return
     */
    @RequestMapping("queryProcessTaskFlowed/{procId}")
    public Result queryProcessTaskFlowed(@PathVariable("procId") String procId, @UIParam("pager") Pager pager) {
        List<ViewProcessTask> list = processService.queryProcessTaskFlowed(procId, pager);
        ViewProcessIns procIns = processService.queryOneProcessIns(procId);
        return ajaxReGrid("gdata", taskFlowCategories(), list, pager).addData("procIns",procIns);
    }
    
    
    /**
     * 查询流程实例任务执行列表
     *
     * @param procId
     * @return
     */
    @RequestMapping("queryTasksByProcForTree")
    public List<TreeBean> queryTasksByProcForTree(String procId) {
        return processService.queryTasksByProcForTree(procId);
    }
    
    @RequestMapping("start")
    public Result start(String userId, String tenantId, String defKey, String businessKey, String
            jsonVariables) throws WorkflowException {
        
        Map<String,Object> result = ProcessUtil.start(userId, StringUtils.isBlank(tenantId) ? "1" : tenantId, defKey, businessKey,
                                             jsonVariables
        );
        return ajaxRe(true).addAllData(result);
    }
    
    @RequestMapping("pass")
    public Result pass(String userId, String procId, String taskId, String jsonVariables, String
            remark) throws WorkflowException {
        ProcessUtil.completeWithGlobalVariables(userId, procId, taskId, jsonVariables, remark);
        return ajaxRe(true);
    }
    
    @RequestMapping("back")
    public Result back(String userId, String procId, String taskId,String remark) {
        ProcessUtil.back(userId, procId, taskId,remark);
        return ajaxRe(true);
    }
    
    @RequestMapping("backTarget")
    public Result backTarget(String userId, String procId, String taskId, String targetTaskKey,String remark) {
        ProcessUtil.backTarget(userId, procId, taskId, targetTaskKey, remark);
        return ajaxRe(true);
    }
    
    @RequestMapping("claim")
    public Result claim(String userId, String taskId,String remark) throws WorkflowException {
        ProcessUtil.claim(userId, taskId,remark);
        return ajaxRe(true);
    }
    
    @RequestMapping("unClaim")
    public Result unClaim(String userId, String taskId,String remark) throws WorkflowException {
        ProcessUtil.unClaim(userId, taskId,remark);
        return ajaxRe(true);
    }
    
    @RequestMapping("queryTaskComments/{taskId}")
    public Result queryTaskComments(@PathVariable("taskId") String taskId) {
        List<TaskComment> taskComments = ProcessUtil.queryTaskComments(taskId);
        List<GridResult.Category> categories = new ArrayList<>();
        categories.add(new GridResult.Category("时间", "time"));
        categories.add(new GridResult.Category("审批意见", "comment"));
        categories.add(new GridResult.Category("处理人", "userName"));
        return ajaxReGrid("gdata",categories,taskComments);
    }
    
    private void copyPic(InputStream in, OutputStream out) {
        try {
            IOUtils.copy(in, out);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            IOUtils.closeQuietly(in);
            IOUtils.closeQuietly(out);
        }
    }
    
    private List<GridResult.Category> categories(){
        List<GridResult.Category> categories = new ArrayList<>();
        categories.add(new GridResult.Category("工单号", "sn"));
        categories.add(new GridResult.Category("工单类型", "procName"));
        categories.add(new GridResult.Category("工单内容", "orderContent"));
        categories.add(new GridResult.Category("任务名称", "name"));
        categories.add(new GridResult.Category("发起人", "startUserName"));
        categories.add(new GridResult.Category("创建时间", "createTime"));
        return categories;
    }
    
    private List<GridResult.Category> completeCategories(){
        List<GridResult.Category> categories = new ArrayList<>();
        categories.add(new GridResult.Category("工单号", "sn"));
        categories.add(new GridResult.Category("工单类型", "procName"));
        categories.add(new GridResult.Category("工单内容", "orderContent"));
        categories.add(new GridResult.Category("任务名称", "name"));
        categories.add(new GridResult.Category("发起人", "startUserName"));
        categories.add(new GridResult.Category("审批人", "assigneeName"));
        //categories.add(new GridResult.Category("下一步审批人", "nextAssigneeName"));
        categories.add(new GridResult.Category("完成时间", "endTime"));
        return categories;
    }
    
    private List<GridResult.Category> notPassCategories(){
        List<GridResult.Category> categories = categories();
        categories.remove(0);
        return categories;
    }
    
    private List<GridResult.Category> taskFlowCategories(){
        List<GridResult.Category> categories = new ArrayList<>();
        categories.add(new GridResult.Category("完成时间", "endTime"));
        categories.add(new GridResult.Category("任务名称", "name"));
        categories.add(new GridResult.Category("处理人", "assigneeName"));
        categories.add(new GridResult.Category("当前审批人", "nextText"));
        categories.add(new GridResult.Category("处理意见", "comment"));
        return categories;
    }
    
    private List<GridResult.Category> categoriesHasAssignee(){
        List<GridResult.Category> categories = categories();
        categories.add(4,new GridResult.Category("处理人", "assigneeName"));
        return categories;
    }

    /*
    @RequestMapping("test")
    public Result testGrid(){
        MenuService menuService = SpringContextUtil.getBean(MenuService.class);
        List<Menu> menus = menuService.queryFull();
        menus = menus.subList(0,15);
        
        
        menus.forEach(menu -> {
            menu.addExtData("ckb","1,2");
            menu.addExtData("rd","1");
            menu.addExtData("span",menu.getCode());
        });
        
        List<GridResult.Category> categories = new ArrayList<>();
        categories.add(new GridResult.Category("菜单名", "name"));
        categories.add(new GridResult.Category("排序", "sort"));
        categories.add(new GridResult.Category("编码", "code"));
        categories.add(new GridResult.Category("是否可用", "enabled"));
        categories.add(new GridResult.Category("复选框", "ckb"));
        categories.add(new GridResult.Category("单选框", "rd"));
        categories.add(new GridResult.Category("三生三世", "span"));
        return ajaxReGrid("gdata",categories,menus);
    }*/
    /**
     * 点击流程图环节，显示环节名和处理人
     * @param procId
     * @return
     */
    @RequestMapping("queryProcessTaskAssignee")
    public Result queryProcessTaskAssignee(String procId) {
        List<ViewProcessTask> list = processService.queryProcessTaskAssignee(procId);
        return ajaxReData("gdata", list);
    }
}
